import type { IChatWebSocket, WebSocketEvent, WebSocketCallback } from '@/types/websocket'

export class ChatWebSocket implements IChatWebSocket {
  private url: string
  private socket: WebSocket | null = null
  private listeners: Record<WebSocketEvent, WebSocketCallback[]> = {
    open: [],
    message: [],
    close: [],
    error: [],
  }

  constructor(url: string) {
    this.url = url
  }

  connect(): void {
    this.socket = new WebSocket(this.url)

    this.socket.onopen = (event: Event) => {
      this.listeners.open.forEach((cb) => cb(event))
    }

    this.socket.onmessage = (event: MessageEvent) => {
      try {
        const data = JSON.parse(event.data)
        this.listeners.message.forEach((cb) => cb(data))
      } catch (error) {
        console.error('Failed to parse WebSocket message:', error)
      }
    }

    this.socket.onclose = (event: CloseEvent) => {
      this.listeners.close.forEach((cb) => cb(event))
    }

    this.socket.onerror = (error: Event) => {
      this.listeners.error.forEach((cb) => cb(error))
    }
  }

  send(message: unknown): boolean {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(message))
      return true
    }
    return false
  }

  close(): void {
    if (this.socket) {
      this.socket.close()
    }
  }

  on(event: WebSocketEvent, callback: WebSocketCallback): void {
    this.listeners[event].push(callback)
  }

  off(event: WebSocketEvent, callback: WebSocketCallback): void {
    this.listeners[event] = this.listeners[event].filter((cb) => cb !== callback)
  }
}
